package com.ricervcvcer.user.service.impl;

import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ricervcvcer.common.dto.UserDTO;
import com.ricervcvcer.user.entity.SysGroup;
import com.ricervcvcer.user.entity.SysRole;
import com.ricervcvcer.user.entity.SysUser;
import com.ricervcvcer.user.mapper.SysGroupMapper;
import com.ricervcvcer.user.mapper.SysPermisMapper;
import com.ricervcvcer.user.mapper.SysRoleMapper;
import com.ricervcvcer.user.mapper.SysUserMapper;
import com.ricervcvcer.user.service.ISysUserService;
import com.ricervcvcer.user.util.RicervcvcerConstant;
import com.ricervcvcer.user.vo.SysUserRoleGroup;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author moge
 * @since 2022-01-10
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService, UserDetailsService {

    @Resource
    private SysPermisMapper permisMapper;

    @Resource
    private SysUserMapper userMapper;

    @Resource
    private SysGroupMapper groupMapper;

    @Resource
    private SysRoleMapper roleMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //1.根据账号去数据库查询，看看是否有这个用户
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("usr_name", username);
//        redisTemplate.
        SysUser user = this.getOne(queryWrapper);
        //如果通过账号在数据库中没有找到对应的用户数据
        if (user == null) {
            return null;
        }

        //2.匹配密码是否正确
        //根据角色编号查询出当前用户所具有的权限
        String[] permisstions = null;
        if (user.getUsrGrpId() != null) {
            List<String> list = permisMapper.selectPerContentByGrpId(user.getUsrGrpId());
            permisstions = new String[list.size()];
            //将集合转型成数组
            list.toArray(permisstions);
        }

        //3.将用户对象转成UserDTO，再将UserDTO编码成Base64格式字符串
        UserDTO userDTO = new UserDTO();
        userDTO.setUsrId(user.getUsrId());
        userDTO.setUsrName(user.getUsrName());
        String json = JSON.toJSONString(userDTO);
        String encode = Base64.encode(json);

        return User.withUsername(encode).password(user.getUsrPassword()).authorities(permisstions).build();
    }

    @Override
    public Page getUsers(String uName, Integer page, Integer rows) {

        // 分页查询所有用户
        Page pages = new Page(page, rows);
        QueryWrapper<SysUser> wrapper = new QueryWrapper();
        wrapper.ne("usr_flag", 0);
        pages = userMapper.selectPage(pages, wrapper);

        // 查询用户对应的权限
        List<SysUser> records = pages.getRecords();
        List<SysUserRoleGroup> sysUserRoleGroupList = records.stream().map((res) -> {
            SysUserRoleGroup sysUserRoleGroup = new SysUserRoleGroup();

            BeanUtils.copyProperties(res, sysUserRoleGroup);

            Integer usrGrpId = res.getUsrGrpId();
            Integer usrRoleId = res.getUsrRoleId();

            // 根据组id查询组名称
            QueryWrapper<SysGroup> qw = new QueryWrapper();
            qw.eq("grp_id", usrGrpId);
            SysGroup sysGroup = groupMapper.selectOne(qw);
            if (null != sysGroup) {
                sysUserRoleGroup.setGrpName(sysGroup.getGrpName());
            }
            // 查询用户的角色
            QueryWrapper<SysRole> qwsr = new QueryWrapper();
            qwsr.eq("role_id", usrRoleId);
            SysRole sysRole = roleMapper.selectOne(qwsr);
            if (null != sysRole) {
                sysUserRoleGroup.setRoleName(sysRole.getRoleName());
            }
            return sysUserRoleGroup;
        }).collect(Collectors.toList());

        // 过滤条件
        sysUserRoleGroupList = filterResource(sysUserRoleGroupList, uName);

        pages.setRecords(sysUserRoleGroupList);
        return pages;
    }

    /**
     * 过滤集合资源
     * @param sysUserRoleGroupList 集合
     * @param uName 条件
     * @return
     */
    private List<SysUserRoleGroup> filterResource(List<SysUserRoleGroup> sysUserRoleGroupList, String uName) {
        return sysUserRoleGroupList.stream().filter((item) -> {
            if (item.getRoleName().contains(uName) ||
                    item.getGrpName().contains(uName) ||
                    item.getUsrName().contains(uName)) {
                return true;
            }
            return false;
        }).collect(Collectors.toList());
    }

    @Override
    public boolean addUser(SysUser user) {
        // 对用户密码进行加密
        String encode = new BCryptPasswordEncoder().encode(user.getUsrPassword());
        user.setUsrPassword(encode);
        // 设置用户flag
        user.setUsrFlag(1);
        boolean save = this.save(user);
        if (!save) {
            throw new RuntimeException(RicervcvcerConstant.ADD_ERROR);
        }
        return true;
    }

    @Override
    public boolean update(SysUser user) {
        if (Objects.isNull(user)) {
            throw new RuntimeException(RicervcvcerConstant.MESSAGE_STRING_INVALIDATE);
        }
        boolean b = this.updateById(user);
        if (!b) {
            throw new RuntimeException(RicervcvcerConstant.UPDATE_ERROR);
        }
        return true;
    }

    @Override
    public boolean isExits(SysUser user) {
        String usrName = user.getUsrName();
        // 查询用户是否存在
        QueryWrapper usr_name = new QueryWrapper<>().select().eq("usr_name", usrName);
        SysUser one = this.getOne(usr_name);
        if (null != one) {
            throw new RuntimeException(RicervcvcerConstant.MESSAGE_ROLE_UNIQUE);
        }
        return this.addUser(user);
    }
}
